#ifndef FRAMEOPENGLWIDGET_H
#define FRAMEOPENGLWIDGET_H

#include <QOpenGLWidget>
#include <QOpenGLShaderProgram>
#include <QOpenGLFunctions>

//帧数据格式
enum FrameDataFormat
{
    FrameDataFormat_None         =  -1,
    FrameDataFormat_RGB24        =   0,
    FrameDataFormat_RGB32        =   1,
    FrameDataFormat_YUV420P      =   2,
    FrameDataFormat_NV12         =   3,
};

class FrameOpenGLWidget : public QOpenGLWidget, protected QOpenGLFunctions
{
public:
    FrameOpenGLWidget(QWidget *parent = nullptr);
    virtual ~FrameOpenGLWidget();

    void  setFrameDataFormat(FrameDataFormat eFrameDataFormat);
    FrameDataFormat getFrameDataFormat();

    //更新NV12帧数据
    void updateNV12Frame(const uint8_t* yData, const uint8_t* uvData, int y_linesize, int uv_linesize, int width, int height);
    //更新YUV420P数据
    void updateYUV420PFrame(const uint8_t* yData, const uint8_t* uData, const uint8_t* vData, int y_linesize, int u_linesize,  int v_linesize, int width, int height);
    //更新RGB24数据
    void updateRGB24Frame(const uint8_t* rgbData, int width, int height, int linesize);
    //更新RGB32数据
    void updateRGB32Frame(const uint8_t* rgbData, int width, int height, int linesize);
    //更新帧数据
    void updateFrame(int eFrameDataFormat,  uint8_t **data, int *linesize, int width, int height);

protected:
    void initializeGL() override;               // 初始化gl
    void resizeGL(int w, int h) override;       // 窗口尺寸变化
    void paintGL() override;                    // 刷新显示

protected:
    void initializeGLByNV12Frame();
    void initTextureByNV12Frame();
    void releaseTextureByNV12Frame();
    void paintGLByNV12Frame();

    void initializeGLByYUV420PFrame();
    void initTextureByYUV420PFrame();
    void releaseTextureByYUV420PFrame();
    void paintGLByYUV420PFrame();

    void initializeGLByRGBFrame();
    void initTextureByRGBFrame();
    void releaseTextureByRGBFrame();
    void paintGLByRGBFrame();

    void initializeGLByRGB32Frame();
    void initTextureByRGB32Frame();
    void releaseTextureByRGB32Frame();
    void paintGLByRGB32Frame();

private:
    QOpenGLShaderProgram m_program;
    GLuint m_yTexture = 0;
    GLuint m_uvTexture = 0;
    GLuint m_uTexture = 0;
    GLuint m_vTexture = 0;
    GLuint m_rgbTexture = 0;
    GLuint m_rgb32Texture = 0;
    uint8_t* m_yData = nullptr;
    uint8_t* m_uvData = nullptr;
    uint8_t* m_uData = nullptr;
    uint8_t* m_vData = nullptr;
    uint8_t* m_nv12Data = nullptr;
    uint8_t* m_rgbData = nullptr;
    uint8_t* m_rgb32Data = nullptr;
    int m_width = 0;
    int m_height = 0;
    QSize  m_size;
    QSizeF  m_zoomSize;
    QPointF m_pos;
    bool m_nFirstUpdateFrame = true;
    int  m_nInitFrameDataFormat = FrameDataFormat_RGB24;
};

#endif // FRAMEOPENGLWIDGET_H
